﻿#region references
using System;
using System.Collections.Generic;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;
using System.IO;
using System.Linq;

/* Project dependencies */
using IcaGames.Objects;
using IcaGames.Logging;
using IcaGames.Database.ObjectManagement;
#endregion

/*
 * UserControl that is used when the user searches for a Game.
 * 
 * The attribute _gvDataSource can be set with the DataSource for the GridView gvSearchResults.
 * The attribute _searchResults can be set with the amount of results that where found.
 */
public partial class usercontrols_SearchResults : System.Web.UI.UserControl
{
    #region public attributes
    public List<Game> _gvGamesDataSource
    {
        set
        {
            gvGameResults.DataSource = value;
            if (_games != null) { _games = value; }
            else { _games = new List<Game>(); _games = value; }
        }
    }

    public List<Publisher> _gvPublisherDataSource
    {
        set
        {
            gvPublisherResults.DataSource = value;
            if (_publishers != null) { _publishers = value; }
            else { _publishers = new List<Publisher>(); _publishers = value; }
        }
    }

    public string _gameSearchResults
    {
        set { lblGameSearchResults.Text = value + " resultaten"; }
    }

    public string _publisherSearchResults
    {
        set { lblPublisherSearchResults.Text = value + " resultaten"; }
    }

    public int _mvActiveViewIndex
    {
        set
        {
            mvSearchResults.ActiveViewIndex = value;
            if (mvSearchResults.ActiveViewIndex == 0)
            {
                lbViewGameResults.Enabled = false;
                lbViewPublisherResults.Enabled = true;
            }
            else
            {
                lbViewGameResults.Enabled = true;
                lbViewPublisherResults.Enabled = false;
            }
        }
    }

    public List<Publisher> _publishers
    {
        set { ViewState["publishers"] = value; }
        get
        {
            List<Publisher> ret = null;
            if (ViewState["publishers"] != null)
                ret = (List<Publisher>)ViewState["publishers"];
            return ret;
        }
    }

    public List<Game> _games
    {
        set { ViewState["games"] = value; }
        get
        {
            List<Game> ret = null;
            if ((List<Game>)ViewState["games"] != null)
                ret = (List<Game>)ViewState["games"];
            return ret;
        }
    }

    public SortDirection _sortDir
    {
        set { ViewState["sortDir"] = value; }
        get
        {
            SortDirection ret = 0;
            if (ViewState["sortDir"] != null)
                ret = (SortDirection)ViewState["sortDir"];
            return ret;
        }
    }

    public int _currentGamesPage
    {
        set { ViewState["currGamesPage"] = value; }
        get
        {
            int ret = 0;
            if (ViewState["currGamesPage"] != null)
                ret = (int)ViewState["currGamesPage"];
            return ret;
        }
    }

    public int _currentPublisherPage
    {
        set { ViewState["currPubPage"] = value; }
        get
        {
            int ret = 0;
            if (ViewState["currPubPage"] != null)
                ret = (int)ViewState["currPubPage"];
            return ret;
        }
    }

    #endregion

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            try
            {
                RegisterJavaScript();
                Session["viewIndex"] = null;

                BindGamesList();
                BindPublisherList();
            }
            catch (Exception)
            {
                /* Set the error message using the ErrorTable UserControl */
                ucErrors._labelText = "Er is een fout opgetreden bij het ophalen van de zoekresultaten. Probeer het nogmaals.";
                ucErrors._pnlVisibility = true;
            }
        }
    }

    /*
     * Function to bind the Publisher GridView to a PagedDataSource to allow paging.
     */ 
    private void BindPublisherList()
    {
        if (_publishers.Count > 0)
        {
            PagedDataSource ds = new PagedDataSource();
            ds.AllowPaging = true;
            ds.DataSource = _publishers;
            ds.PageSize = 10;
            ds.CurrentPageIndex = _currentPublisherPage;

            if (!ds.IsLastPage && !ds.IsFirstPage)
            {
                int pageCount = ds.FirstIndexInPage + (_currentPublisherPage + 10);
                lblCurrentPublisherResults.Text = (ds.FirstIndexInPage + 1).ToString() + " - " + (pageCount - 1).ToString() + " van ";
            }
            else if (ds.IsFirstPage)
            {
                int pageCount = _currentPublisherPage + 10;
                if (_publishers.Count < 10) { pageCount = _publishers.Count; }
                lblCurrentPublisherResults.Text = (ds.FirstIndexInPage + 1).ToString() + " - " + pageCount.ToString() + " van ";
            }
            else if (ds.IsLastPage)
            {
                int pageCount = (ds.FirstIndexInPage + 1) + (_currentPublisherPage + 10);
                lblCurrentPublisherResults.Text = (ds.FirstIndexInPage + 1).ToString() + " - " + _publishers.Count.ToString() + " van ";
            }
            gvPublisherResults.DataSource = ds;
            gvPublisherResults.DataBind();

            lbPublisherNext.Enabled = !ds.IsLastPage;
            lbPublisherPrevious.Enabled = !ds.IsFirstPage;
        }
        else
        {
            gvPublisherResults.DataSource = _publishers;
            gvPublisherResults.DataBind();
            lbPublisherNext.Visible = false;
            lbPublisherPrevious.Visible = false;
        }
    }

    /*
     * Function to bind the Games GridView to a PagedDataSource to allow paging.
     */ 
    private void BindGamesList()
    {
        if (_games.Count > 0)
        {
            PagedDataSource ds = new PagedDataSource();
            ds.AllowPaging = true;
            ds.DataSource = _games;
            ds.PageSize = 5;
            ds.CurrentPageIndex = _currentGamesPage;

            if (!ds.IsLastPage && !ds.IsFirstPage)
            {
                int pageCount = ds.FirstIndexInPage + (_currentGamesPage + 5);
                lblCurrentGameResults.Text = (ds.FirstIndexInPage + 1).ToString() + " - " + (pageCount - 1).ToString() + " van ";
            }
            else if (ds.IsFirstPage)
            {
                int pageCount = _currentGamesPage + 5;
                if (_games.Count < 5) { pageCount = _games.Count; }
                lblCurrentGameResults.Text = (ds.FirstIndexInPage + 1).ToString() + " - " + pageCount.ToString() + " van ";
            }
            else if (ds.IsLastPage)
            {
                int pageCount = (ds.FirstIndexInPage + 1) + (_currentGamesPage + 5);
                lblCurrentGameResults.Text = ds.FirstIndexInPage.ToString() + " - " + _games.Count.ToString() + " van ";
            }

            gvGameResults.DataSource = ds;
            gvGameResults.DataBind();

            lbGamesNext.Enabled = !ds.IsLastPage;
            lbGamesPrevious.Enabled = !ds.IsFirstPage;
        }
        else
        {
            gvGameResults.DataSource = _games;
            gvGameResults.DataBind();
            lbGamesNext.Visible = false;
            lbGamesPrevious.Visible = false;
        }
    }

    /*
     * Function to navigate the Games GridView one page back.
     */ 
    protected void GamesPageBack(object sender, EventArgs e)
    {
        _currentGamesPage -= 1;
        BindGamesList();
    }

    /*
     * Function to navigate the Games GridView one page further.
     */ 
    protected void GamesPageNext(object sender, EventArgs e)
    {
        _currentGamesPage += 1;
        BindGamesList();
    }

    /*
     * Function to navigate the Publishers GridView one page back.
     */ 
    protected void PublishersPageBack(object sender, EventArgs e)
    {
        _currentPublisherPage -= 1;
        BindPublisherList();
    }

    /*
     * Function to navigate the Publishers GridView one page further.
     */ 
    protected void PublishersPageNext(object sender, EventArgs e)
    {
        _currentPublisherPage += 1;
        BindPublisherList();
    }

    /*
     * Function to register the javascript needed for this page.
     */
    private void RegisterJavaScript()
    {
        HtmlGenericControl functions = new HtmlGenericControl("script");
        functions.Attributes.Add("type", "text/javascript");
        functions.Attributes.Add("src", "javascript/functions.js");
        this.Page.Header.Controls.Add(functions);
    }

    /*
     * Function that is executed when the LinkButton containing the Game Title is clicked.
     * 
     * Redirects the user to the detailed information page of the specified Game.
     */
    protected void GetGameDetails(object sender, EventArgs e)
    {
        try
        {
            string queryString = ((LinkButton)sender).CommandArgument;
            string searchText = ((TextBox)Page.Master.FindControl("txtSearch")).Text.Replace(' ', '_');
            Response.Redirect("~/GameDetails.aspx?g=" + queryString +
                "&s=" + searchText);
        }
        catch (Exception)
        {
            /* Set the error message using the ErrorTable UserControl */
            ucErrors._labelText = "Er is een fout opgetreden bij het verwerken van uw verzoek. Probeer het nogmaals.";
            ucErrors._pnlVisibility = true;
        }
    }

    /*
     * Function that is executed when the event RowDataBound is fired.
     * 
     * Get's a thumbnail image for each Publisher in the search results list.
     */
    protected void gvPublisherResults_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        if (e.Row.RowType == DataControlRowType.DataRow)
        {
            ImageButton ibtnPublisherLogo = e.Row.FindControl("ibtnPublisherLogo") as ImageButton;
            if (ibtnPublisherLogo != null)
            {
                string path = Server.MapPath("~/upload/publishers/") + ibtnPublisherLogo.CommandArgument + "/" +
                        ibtnPublisherLogo.CommandArgument + ".jpg";

                if (File.Exists(path))
                {
                    ibtnPublisherLogo.ImageUrl = "../../upload/publishers/" + ibtnPublisherLogo.CommandArgument + "/" +
                        ibtnPublisherLogo.CommandArgument + ".jpg";
                }
                else
                {
                    ibtnPublisherLogo.ImageUrl = "../../img/no-logo.png";
                }
            }
        }
    }

    /*
     * Function that is executed when the Button btnOrderGame is clicked.
     * 
     * Add's the selected Game to the shopping cart of the user.
     */
    protected void AddToCart(object sender, EventArgs e)
    {
        string[] param = ((Button)sender).CommandArgument.Split('_');
        Game g = new Game();
        ShoppingCart c = new ShoppingCart();

        if (GameManagement.GetGame(int.Parse(param[0]), g, param[1]))
        {
            if (Session["cart"] == null) { c.Games = new List<Game>(); }
            else { c = (ShoppingCart)Session["cart"]; }
            c.Games = CartManagement.AddGameToCart(c.CartId, c.Games, g);
            Session["cart"] = c;

            if (Session["cartPrice"] != null)
            {
                if (Page.User.Identity.IsAuthenticated)
                {
                    /* Refresh the shopping cart on the masterpage */
                    decimal[] cartContents = CartManagement.RefreshShoppingCart(c.Games);
                    Session["cartPrice"] = cartContents;

                    LinkButton lbCartInfo = ((LoginView)Page.Master.FindControl("LoginView1")).FindControl("lbCartInfo") as LinkButton;
                    lbCartInfo.Text = cartContents[1] + " artikel(en) totaalprijs: € " + String.Format("{0:0,##}",
                    cartContents[0].ToString().Replace('.', ','));
                }
            }
        }
    }

    /*
     * Function that is executed when the event RowDataBound is fired.
     * 
     * Get's a thumbnail image for each Game in the search results list.
     * Add's a JavaScript function for each Game in the search results list with the original Game image.
     */
    protected void gvGameResults_RowDataBound(object sender, GridViewRowEventArgs e)
    {
        try
        {
            if (e.Row.RowType == DataControlRowType.DataRow)
            {
                ImageButton ibtnGamePicture = e.Row.FindControl("ibtnGamePicture") as ImageButton;
                Label lblGamePrice = e.Row.FindControl("lblGamePrice") as Label;
                LinkButton lbGameTitle = e.Row.FindControl("lbGameTitle") as LinkButton;
                Label lblGameStock = e.Row.FindControl("lblGameStock") as Label;
                Label lblGamePlatform = e.Row.FindControl("lblGamePlatform") as Label;
                Button btnOrderGame = e.Row.FindControl("btnOrderGame") as Button;

                /* Set the Click event for btnOrderGame */
                if (btnOrderGame != null) { btnOrderGame.Click += AddToCart; }

                /* Set the description for the Game Platform */
                if (lblGamePlatform != null)
                {
                    Platform pf = PlatformValue.GetPlatform(lblGamePlatform.Text);
                    lblGamePlatform.Text = PlatformDescription.GetDescription(pf);
                }

                /* Set Click event for lbGameTitle */
                if (lbGameTitle != null) { lbGameTitle.Click += GetGameDetails; }

                /* Set ToolTip for lblGameStock */
                if (lblGameStock != null)
                {
                    if (lblGameStock.Text.Equals("0")) { lblGameStock.ToolTip = "Dit artikel is helaas niet op voorraad"; }
                    else { lblGameStock.ToolTip = "Dit artikel is op voorraad"; }
                }

                /* Set ImageButton ImageUrl */
                if (ibtnGamePicture != null) { SetImageButton(ibtnGamePicture, lblGamePlatform.Text); }

                /* Set the correct format for the Game price */
                if (lblGamePrice != null) { lblGamePrice.Text = "€ " + String.Format("{0:0,##}", lblGamePrice.Text.Replace('.', ',')); }
            }
        }
        catch (Exception ex)
        {
            Log.CreateLog("Exception in gvSearchResults RowDataBound", "SEARCHGAME");
            Log.CreateLog(ex.Message, "SEARCHGAME");
        }
    }

    /*
     * Function to set the ImageUrl for the specified ImageButton.
     * 
     * @param
     * ibtn: The ImageButton for which the ImageUrl has to be set.
     */
    private void SetImageButton(ImageButton ibtn, string platform)
    {
        /* Get the gameNr of the selected game */
        int gameNr = int.Parse(ibtn.CommandArgument);
        int[,] imageSize = new int[1, 2];
        string pf = null;

        /* Get the thumb picture for the selected game */
        System.Drawing.Image thumb = Thumb.GetResizedImage(Server.MapPath("~/upload/"),
            gameNr, platform, imageSize);

        /* Set the ImageUrl of the ImageButton in the GridView */
        if (thumb != null)
        {
            pf = Thumb.GetImagePlatform(platform);
            ibtn.ImageUrl = "../../upload/" + gameNr + "/" + pf + "_thumb.jpg";
            ibtn.ToolTip = "Bekijk afbeelding in originele grootte";
        }
        else
        {
            ibtn.ImageUrl = "../../img/no-image.png";
            ibtn.ToolTip = "Geen afbeelding beschikbaar";
            ibtn.Enabled = false;
        }

        /* Add popup for original image if there is an originale image available */
        if (imageSize[0, 0] != 0 && imageSize[0, 1] != 0)
        {
            ibtn.Attributes.Add("onclick",
                "OpenWindow(" + gameNr + ",'" + pf + "'," + imageSize[0, 0] + "," + imageSize[0, 1] + ")");
        }
    }

    /*
     * Function that sorts the GridView with search results depending on the sort expression.
     */
    protected void SortSearchResults(object sender, GridViewSortEventArgs e)
    {
        IOrderedEnumerable<Game> sortedGames = null;
        switch (e.SortExpression)
        {
            case "Naam":
                if (_sortDir == SortDirection.Ascending) { sortedGames = _games.OrderBy(g => g.Title); _sortDir = SortDirection.Descending; }
                else { sortedGames = _games.OrderByDescending(g => g.Title); _sortDir = SortDirection.Ascending; }
                gvGameResults.DataSource = sortedGames;
                gvGameResults.DataBind();
                break;
            case "Platform":
                if (_sortDir == SortDirection.Ascending) { sortedGames = _games.OrderBy(g => g.Platform.ToString()); _sortDir = SortDirection.Descending; }
                else { sortedGames = _games.OrderByDescending(g => g.Platform.ToString()); _sortDir = SortDirection.Ascending; }
                gvGameResults.DataSource = sortedGames;
                gvGameResults.DataBind();
                break;
            case "Voorraad":
                if (_sortDir == SortDirection.Ascending) { sortedGames = _games.OrderBy(g => g.Stock); _sortDir = SortDirection.Descending; }
                else { sortedGames = _games.OrderByDescending(g => g.Stock); _sortDir = SortDirection.Ascending; }
                gvGameResults.DataSource = sortedGames;
                gvGameResults.DataBind();
                break;
            case "Prijs":
                if (_sortDir == SortDirection.Ascending) { sortedGames = _games.OrderBy(g => g.Price); _sortDir = SortDirection.Descending; }
                else { sortedGames = _games.OrderByDescending(g => g.Price); _sortDir = SortDirection.Ascending; }
                gvGameResults.DataSource = sortedGames;
                gvGameResults.DataBind();
                break;
            default:
                if (_sortDir == SortDirection.Ascending) { sortedGames = _games.OrderBy(g => g.Title); _sortDir = SortDirection.Descending; }
                else { sortedGames = _games.OrderByDescending(g => g.Title); _sortDir = SortDirection.Ascending; }
                gvGameResults.DataSource = sortedGames;
                gvGameResults.DataBind();
                break;
        }
    }

    /*
     * Function that is executed when the LinkButton lbGameResults is clicked.
     * 
     * Display's the View with Game search results.
     */
    protected void SeeViewGameResults(object sender, EventArgs e)
    {
        mvSearchResults.ActiveViewIndex = 0;

        /* Set LinkButton's to enabled or disabled */
        lbViewGameResults.Enabled = false;
        lbViewPublisherResults.Enabled = true;
    }

    /*
     * Function that is executed when the LinkButton lbPublisherResults is clicked.
     * 
     * Display's the View with Publisher search results.
     */
    protected void SeeViewPublisherResults(object sender, EventArgs e)
    {
        mvSearchResults.ActiveViewIndex = 1;

        /* Set LinkButton's to enabled or disabled */
        lbViewGameResults.Enabled = true;
        lbViewPublisherResults.Enabled = false;
    }
}
